<template>
    <div>
        <!-- 面包屑 -->
        <el-breadcrumb separator="/">
        <el-breadcrumb-item :to="{ path: '/index/home' }"
            >首页</el-breadcrumb-item
        >
        <el-breadcrumb-item><a href="#/index/articleList">文章管理</a></el-breadcrumb-item>
        <el-breadcrumb-item>文章发布</el-breadcrumb-item>
        </el-breadcrumb>
        <!-- 包含阴影的组件 卡片组件 -->
        <el-card>
            <!-- 表单组件 -->
            <el-form ref="form" :model="form" label-width="80px">
                <!-- 标题 -->
                <el-form-item label="标题">
                    <el-input v-model="form.title"></el-input>
                </el-form-item>
                <!-- 类型 -->
                <el-form-item label="类型">
                    <!-- label属性的值 和form.type双向绑定了 -->
                    <el-radio-group v-model="form.type" @change="typeChangeFn">
                        <el-radio :label="1">文章</el-radio>
                        <el-radio :label="2">视频</el-radio>
                    </el-radio-group>
                </el-form-item>
                <!-- 内容
                    当用户选择文章类型的时候，显示富文本编辑器
                    当用户选择视频类型的时候，显示视频上传按钮
                 -->
                 <el-form-item label="内容">
                     <!-- 富文本
                        使用步骤：
                            1、下载npm i vue-word-editor
                            2、引入
                                import VueEditor from "vue-word-editor";
                                import "quill/dist/quill.snow.css"
                            3、注册
                                components: {
                                    VueEditor
                                },
                            4、使用
                                <VueEditor></VueEditor>
                            5、给组件添加配置
                                5-1、在data中声明配置
                                    config: {
                                        // 上传图片的配置
                                        uploadImage: {
                                            url: "http://localhost:3000/upload",
                                            name: "file",
                                            // res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
                                            uploadSuccess(res, insert){
                                            insert("http://localhost:3000" + res.data.url)
                                            }
                                        },
                                    }
                                5-2、给组件标签绑定配置
                                    <VueEditor :config="config"></VueEditor>
                      -->
                    <VueEditor v-if="form.type==1" ref="vueEditor" :config="config"></VueEditor>
                     <!-- 视频上传按钮 
                        action: 设置上传文件的接口地址（包括基础路径）
                        limit：限制文件上传数量
                        file-list：文件列表，设置默认显示的文件
                        accept: 设置文件上传类型
                        on-success: 视频上传成功的钩子(属性)
                        on-remove：文件列表移除文件时的钩子
                        on-exceed: 文件超出个数时的钩子
                     -->
                     <el-upload
                        v-if="form.type==2"
                        class="upload-demo"
                        :action="baseURL+'/upload'"
                        :headers="headers"
                        :limit="1"
                        :file-list="videoList"
                        :on-success="videoSuccessFn"
                        :on-remove="videoRemoveFn"
                        :on-exceed="videoExceedFn"
                        accept="video/mp4">
                        <el-button size="small" type="primary">点击上传</el-button>
                        <div slot="tip" class="el-upload__tip">只能上传视频 mp4文件，且不超过2M</div>
                    </el-upload>
                 </el-form-item>
                <!-- 栏目 -->
                <el-form-item label="栏目">
                    <!-- 
                        indeterminate: true表示不确定状态 false表示确定状态
                        v-model：布尔值，表示当前的全选状态 
                        change：全选框改变是触发的事件
                     -->
                    <el-checkbox 
                    :indeterminate="isIndeterminate" 
                    v-model="checkAll" 
                    @change="handleCheckAllChange">全选</el-checkbox>
                    <div style="margin: 15px 0;"></div>
                    <!-- 
                        v-model：表示选中的数据集合（默认选中的选项）
                        change：小选框改变时触发的事件
                     -->
                    <el-checkbox-group v-model="form.categories" 
                    @change="handleCheckedCtegoryChange">
                        <!-- 
                            v-for：循环数据源
                            label：值和checkbox-group的v-model绑定的变量双向邦定在一起
                         -->
                        <el-checkbox v-for="item in categoryList" 
                        :label="item.id" :key="item.id">{{item.name}}</el-checkbox>
                    </el-checkbox-group>
                </el-form-item>
                <!-- 封面 -->
                <el-form-item label="封面">
                    <el-upload
                    :action="baseURL+'/upload'"
                    :headers="headers"
                    :limit="3"
                    :file-list="form.cover"
                    :on-success="coverSuccessFn"
                    :on-remove="coverRemoveFn"
                    :on-exceed="coverExceedFn"
                    list-type="picture-card">
                    <i class="el-icon-plus"></i>
                    </el-upload>
                </el-form-item>
                <!-- 发布按钮 -->
                <el-button type="primary" @click="sendFn" >发布</el-button>
            </el-form>
        </el-card>
    </div>
</template>

<script>
import VueEditor from "vue-word-editor";
import "quill/dist/quill.snow.css"
import axios from "@/utils/request.js"
import { category,send, articleDetail,articleUpdate } from "@/api/article.js"
export default {
    components: {
        VueEditor
    },
    data(){
        return {
            checkAll: false,
            isIndeterminate: false,
            categoryList: [],  // 栏目列表数据源
            baseURL: axios.defaults.baseURL,
            headers: {
                Authorization: localStorage.getItem('72-backend-token')
            },
            videoList: [], // 视频列表
            form: {
                title: "", // 标题
                type: 1,
                content: "",
                categories: [], // 栏目id集合
                cover:[],       // 封面id集合
            },
            config: {
                // 上传图片的配置
                uploadImage: {
                    url: axios.defaults.baseURL+"/upload",
                    name: "file",
                    headers: {
                        Authorization: localStorage.getItem("72-backend-token")
                    },
                    // res是结果，insert方法会把内容注入到编辑器中，res.data.url是资源地址
                    uploadSuccess(res, insert){
                        // console.log(res);
                        insert(axios.defaults.baseURL + res.data.data.url)
                    }
                },
            },
            article: {} // 文章详情
        }
    },
    created(){
        // 获取栏目列表数据
        category().then(res=>{
            // console.log(163,res);
            // 栏目不需要展示“关注”和“头条”
            this.categoryList = res.data.data.slice(2);
        })

        // 获取文章详情数据
        // 当id存在时表示需要进行文章编辑，否则新增文章
        if(this.$route.query.id){
            articleDetail(this.$route.query.id).then(res=>{
                // console.log(187,res);
                this.article = res.data.data;
                // 进行内容的回显
                // 标题
                this.form.title = this.article.title;
                // 类型
                this.form.type = this.article.type;
                // 内容  视频或者富文本
                if(this.form.type == 1){
                    // 富文本
                    var quill = this.$refs.vueEditor.editor; 
                    quill.clipboard.dangerouslyPasteHTML(0,this.article.content);
                    this.form.content = this.article.content;
                }else{
                    this.form.content = this.article.content;
                    // 回显在浏览器中
                    this.videoList.push({
                        name: "小视频",
                        url: this.article.content
                    })
                }
                // 栏目
                this.form.categories = this.article.categories.map(item=>item.id);
                // 设置全选框状态
                this.handleCheckedCtegoryChange(this.form.categories)
                // 封面
                this.form.cover = this.article.cover.map(item=>{
                    return {
                        id: item.id,
                        url: this.baseURL+item.url
                    }
                });
            })
        }
    },
    methods: {
        // 类型改变时触发
        typeChangeFn(){
            // console.log(186);
            // 类型改变时清空内容
            this.form.content = "";
        },
        // 上传封面数量超出规定时触发的钩子函数
        coverExceedFn(){
            this.$message({
                type: "warning",
                message: "封面最多只能上传3张!"
            })
        },
        // 移除封面钩子
        coverRemoveFn(file,fileList){
            // file 表示被删除的文件对象
            // fileList 剩下的文件对象集合
            // console.log(file,fileList);
            this.form.cover = fileList;
        },
        //上传封面成功的钩子 
        coverSuccessFn(file){
            // console.log(183,file);
            this.form.cover.push({
                id: file.data.id,
                url: this.baseURL + file.data.url
            })
        },
        // 全选功能实现
            handleCheckAllChange(val) {
                // val
                // console.log(val,this.checkAll);
                // 当val值为true时，把所有栏目的id添加到form.categoreis数组中即可实现全选功能
                this.form.categories = val?this.categoryList.map(item=>item.id):[]
                // 当用户点击全选按钮的时候，只有2种情况，全选或者全部不选，此刻处于确定状态
                this.isIndeterminate = false;
            },
            // 小选影响全选的功能实现
            handleCheckedCtegoryChange(value) {
                // value 就是选中的选项集合
                // console.log(value,this.form.categories);
                // 设置全选状态，当选中的选项集合长度等于所有栏目数据的长度
                // 此时，处于全选状态
                this.checkAll = value.length==this.categoryList.length;
                // 设置不确定状态，当选中的选项结合长度大于0且小于所有栏目数据的长度
                // 的时候，处于不确定状态
                this.isIndeterminate = value.length>0&&value.length<this.categoryList.length;
            },
        // 发布文章
        sendFn(){
            // 标题
            if(!this.form.title){
                // 这种写法和下面写法等价
                this.$message.warning("标题不能为空！")
                // this.$message({
                //     type: "warning",
                //     message: "标题不能为空！"
                // })
                return
            }
            // 内容
            // 文章内容,当类型为“文章”的时候 获取富文本内容
            if(this.form.type == 1){
                // 文章
                // let txt = this.$refs.vueEditor.editor.root.innerText;
                // if(txt === '\n'){
                //     return this.$message.warning("内容不能为空！")
                // }
                // 富文本内容为空的时候会有一个换行符存在，因此富文本提供了一个方法getLength来判断
                // 富文本内容是否为空，当getLength值为1时，表示富文本内容为空，否则不为空。
                let length = this.$refs.vueEditor.editor.getLength();
                if(length == 1){
                    return this.$message.warning("内容不能为空！")
                }
                this.form.content = this.$refs.vueEditor.editor.root.innerHTML; 
            }else{
                // 视频
                if(!this.form.content){
                    return this.$message.warning("内容(视频)不能为空！")
                }
            }
            //栏目
            if(this.form.categories.length == 0){
                return this.$message.warning("栏目至少选择一个！")
            }
            // 封面
            if(this.form.cover.length === 0){
                return this.$message.warning("封面至少上一张！")
            }

            // 改造categories中的数据结构, 后台规定栏目的数据结构必须数组对象
            let categories = this.form.categories.map(id=>{
                return {
                    id: id
                }
            })
            // console.log(280,categories);
            if(this.$route.query.id){
                // 编辑
                articleUpdate( this.$route.query.id,{
                    ...this.form,
                    categories
                }).then(res=>{
                    // console.log(325,res);
                    if(res.data.message === "文章编辑成功"){
                        this.$router.push("/index/articleList")
                        this.$message.success(res.data.message)
                        return
                    }
                    this.$message.error(res.data.message)
                })
                return
            }
            //调用 发布文章接口
            send({
                ...this.form,
                categories
            }).then(res=>{
                console.log(286,res);
                if(res.data.message =="文章发布成功"){
                    // 跳转到文章列表页面
                    this.$router.push("/index/articleList")
                    this.$message.success(res.data.message)
                }else{
                    this.$message.error(res.data.message)
                }
            })
        },
        // 视频上传成功的钩子函数
        videoSuccessFn(response){
            // console.log(response);
            this.videoList.push({
                name: "小视频",
                ...response.data
            })
            // 保存上传的视频链接地址
            this.form.content = response.data.url
        },
        // 移除视频，同时移除数据
        videoRemoveFn(){
            // console.log(file,fileList);
            this.videoList = [];
            this.form.content = "";
        },
        // 用户上传文件超出规定数量时触发
        videoExceedFn(){
            this.$message({
                type: "warning",
                message: "视频只能上传一个！"
            })
        }
    }
}
</script>

<style lang="less" scoped>
.el-card{
    margin-top: 20px;
}
</style>